In [2]:
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import display, HTML, Markdown
from legacy_lcgs import *
In [3]:
RNG = 'default_rng'
SEED = 2653589793
VERTICES = 4
COORDS = 3000
In [4]:
Markdown(f"""# Chaos Game Class Demo with {RNG} Random Number Generator
By Katie Wuestney""")
Out[4]:

Chaos Game Class Demo with <function LCG at 0x000001D15533F430> Random Number Generator¶

By Katie Wuestney

In [5]:
if RNG == 'default_rng':
    rng = np.random.default_rng()
elif RNG == 'LCG':
    rng = LCG()
elif RNG == 'Mersenne':
    rng = np.random.Generator(np.random.MT19937())
elif RNG == 'RANDU':
    rng = RANDU(33)
elif RNG == 'PASCAL':
    rng = PASCAL(33)
In [6]:
def ngon_coords(verts):
    radians=[]
    for k in range(verts):
        rad = (2*np.pi*k)/verts
        radians.append(rad)
    x_vals = np.cos(radians)
    y_vals =np.sin(radians)
    return x_vals, y_vals
In [7]:
class chaos_game:
    def __init__(self, verts, points, RNG=np.random.default_rng()):
        #self.fig = fig
        #self.ax = ax
        self.verts = verts
        self.points = points
        #get vertex coordinates
        x_vals, y_vals = ngon_coords(verts)
        self.x_vals = x_vals
        self.y_vals = y_vals
        vert_coords = np.column_stack((x_vals, y_vals))
        xmin = x_vals.min() - 0.2
        xmax = x_vals.max() + 0.2
        ymin = y_vals.min() - 0.2
        ymax = y_vals.max() + 0.2
        self.xlims = (xmin, xmax)
        self.ylims = (ymin, ymax)
        #c is starting coordinate
        c = np.array([0.0, 0.25])

        #initiate figure instance
        self.fig, self.ax = plt.subplots(figsize=(4, 4))
        self.ax.set(xlim=self.xlims, ylim=self.ylims)
        rng = RNG
        self.randints = rng.integers(0, verts, points)
#         if RNG == 'default_rng':
#             rng = np.random.default_rng()
#             self.randints = rng.integers(0, verts, points)
#         elif RNG == 'LCG':
#             rng = LCG()
#             self.randints = list(rng.ints(0, verts, points))
#         elif RNG == 'Mersenne':
#             rng = np.random.Generator(np.random.MT19937())
#             self.randints = rng.integers(0, verts, points)
#         elif RNG == 'RANDU':
#             rng = RANDU(33)
#             self.randints = list(rng.ints(0, verts, points))
#         elif RNG == 'PASCAL':
#             rng = PASCAL(33)
#             self.randints = list(rng.ints(0, verts, points))
        coords = [c]
        #firstpts = 10
        for i in self.randints:
            coords.append((coords[-1] + vert_coords[i])/2)
        self.coords = coords[1:]
        
    def plot(self):
        x, y = zip(*self.coords)
        self.ax.scatter(self.x_vals, self.y_vals, c='b', label='vertices')
        self.ax.legend()
        for i, xy in enumerate(zip(self.x_vals, self.y_vals)):
            self.ax.annotate(f'{i}', xy, xycoords='data', xytext=(4,4), textcoords='offset points')
        self.ax.scatter(x, y, s=1, c='g')
        return
        
    def savefig(self, filename, **kwargs):
        self.fig.savefig(filename, **kwargs)
        return

    def init_frame(self):
        self.ax.cla()
        self.ax.set(xlim=self.xlims, ylim=self.ylims)
        self.ax.scatter(x=0, y=0.25, s=1, c='r', label='inital point')
        self.ax.scatter(self.x_vals, self.y_vals, c='b', label='vertices')
        self.ax.legend()
        for i, xy in enumerate(zip(self.x_vals, self.y_vals)):
            self.ax.annotate(f'{i}', xy, xycoords='data', xytext=(4,4), textcoords='offset points')
        return
    
    def animation(self, i):
        i_from = i * self.chunks
        # are we on the last frame?
        if i_from + self.chunks > len(self.coords) - 1:
            i_to = len(self.coords) - 1
        else:
            i_to = i_from + self.chunks
        rows = self.coords[i_from:i_to]
        x, y = zip(*rows)
        self.ax.scatter(x, y, s=1, c='g')
        return
    
    def animate(self, chunks=20):
        self.chunks = chunks
        self.frame_chunks = self.points // self.chunks
        self.ani = FuncAnimation(self.fig, self.animation, frames=self.frame_chunks, init_func=self.init_frame, interval=5, repeat=True, blit=True)
        plt.show()
        
    def movie(self):
        movie1 = self.ani.to_jshtml()
        return movie1
    
    def pause(self):
        self.ani.pause()
        return
In [8]:
cg = chaos_game(VERTICES, COORDS)
cg.animate()
In [8]:
mv = cg.movie()
HTML(mv)
Out[8]: